package controllers

import (
	"net/http"
	"strconv"

	"github.com/gin-gonic/gin"
	"github.com/inntu/backend/api/models"
	"github.com/inntu/backend/api/services"
	"github.com/inntu/backend/utils"
)

// PageController 页面控制器
type PageController struct {
	pageService *services.PageService
}

// NewPageController 创建页面控制器实例
func NewPageController() *PageController {
	return &PageController{
		pageService: services.NewPageService(),
	}
}

// GetPageWithCategoriesAndItems 获取页面的完整结构（兼容旧API）
// @Summary 获取页面数据
// @Description 根据页面名称获取页面及其分类和项目的完整层级结构
// @Tags 页面管理
// @Accept json
// @Produce json
// @Param page_name path string true "页面名称"
// @Success 200 {object} utils.Response{data=models.Page} "成功"
// @Failure 400 {object} utils.Response "请求参数错误"
// @Failure 404 {object} utils.Response "页面不存在"
// @Failure 500 {object} utils.Response "服务器错误"
// @Router /api/v1/page/{page_name} [get]
func (pc *PageController) GetPageData(c *gin.Context) {
	pageName := c.Param("page_name")

	// 验证页面名称 TODO 少了个“我的”
	// validPages := map[string]bool{
	// 	"home":      true,
	// 	"functions": true,
	// 	"ntu_intro": true,
	// 	"ntu_guide": true,
	// }

	// if !validPages[pageName] {
	// 	utils.ErrorResponse(c, http.StatusBadRequest, "无效的页面名称")
	// 	return
	// }

	// TODO 获取页面数据 但函数名不对
	page, err := pc.pageService.GetPageWithCategoriesAndItems(c, pageName)
	if err != nil {
		if err.Error() == "页面不存在" {
			utils.ErrorResponse(c, http.StatusNotFound, err.Error())
		} else {
			utils.ErrorResponse(c, http.StatusInternalServerError, err.Error())
		}
		return
	}

	utils.SuccessResponse(c, "获取页面数据成功", page)
}

// GetPages 获取页面列表
// @Summary 获取页面列表
// @Description 获取所有启用的页面列表
// @Tags 页面管理
// @Accept json
// @Produce json
// @Success 200 {object} utils.Response{data=[]models.Page} "成功"
// @Failure 500 {object} utils.Response "服务器错误"
// @Router /api/v1/pages [get]
func (pc *PageController) GetPages(c *gin.Context) {
	pages, err := pc.pageService.GetPages(c)
	if err != nil {
		utils.ErrorResponse(c, http.StatusInternalServerError, err.Error())
		return
	}

	utils.SuccessResponse(c, "获取页面列表成功", pages)
}

// GetPageByCode 根据代码获取页面详情
// @Summary 根据代码获取页面详情
// @Description 根据页面代码获取页面的详细信息
// @Tags 页面管理
// @Accept json
// @Produce json
// @Param code path string true "页面代码"
// @Success 200 {object} utils.Response{data=models.Page} "成功"
// @Failure 404 {object} utils.Response "页面不存在"
// @Failure 500 {object} utils.Response "服务器错误"
// @Router /api/v1/pages/code/{code} [get]
func (pc *PageController) GetPageByCode(c *gin.Context) {
	code := c.Param("code")
	if code == "" {
		utils.ErrorResponse(c, http.StatusBadRequest, "页面代码不能为空")
		return
	}

	page, err := pc.pageService.GetPageByCode(c, code)
	if err != nil {
		if err.Error() == "页面不存在" {
			utils.ErrorResponse(c, http.StatusNotFound, err.Error())
		} else {
			utils.ErrorResponse(c, http.StatusInternalServerError, err.Error())
		}
		return
	}

	utils.SuccessResponse(c, "获取页面详情成功", page)
}

// GetPageWithCategories 获取页面及其分类
// @Summary 获取页面及其分类
// @Description 根据页面代码获取页面及其关联的分类列表
// @Tags 页面管理
// @Accept json
// @Produce json
// @Param code path string true "页面代码"
// @Success 200 {object} utils.Response{data=models.Page} "成功"
// @Failure 404 {object} utils.Response "页面不存在"
// @Failure 500 {object} utils.Response "服务器错误"
// @Router /api/v1/pages/{code}/categories [get]
func (pc *PageController) GetPageWithCategories(c *gin.Context) {
	code := c.Param("code")
	if code == "" {
		utils.ErrorResponse(c, http.StatusBadRequest, "页面代码不能为空")
		return
	}

	page, err := pc.pageService.GetPageWithCategories(c, code)
	if err != nil {
		if err.Error() == "页面不存在" {
			utils.ErrorResponse(c, http.StatusNotFound, err.Error())
		} else {
			utils.ErrorResponse(c, http.StatusInternalServerError, err.Error())
		}
		return
	}

	utils.SuccessResponse(c, "获取页面分类成功", page)
}

// GetPageByID 根据ID获取页面详情（管理端）
// @Summary 根据ID获取页面详情
// @Description 根据页面ID获取页面的详细信息
// @Tags 页面管理
// @Accept json
// @Produce json
// @Param id path int true "页面ID"
// @Success 200 {object} utils.Response{data=models.Page} "成功"
// @Failure 404 {object} utils.Response "页面不存在"
// @Failure 500 {object} utils.Response "服务器错误"
// @Router /api/v1/admin/pages/{id} [get]
func (pc *PageController) GetPageByID(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.Atoi(idStr)
	if err != nil {
		utils.ErrorResponse(c, http.StatusBadRequest, "无效的页面ID")
		return
	}

	page, err := pc.pageService.GetPageByID(c, id)
	if err != nil {
		utils.ErrorResponse(c, http.StatusNotFound, err.Error())
		return
	}

	utils.SuccessResponse(c, "获取页面详情成功", page)
}

// CreatePage 创建页面（管理端）
// @Summary 创建页面
// @Description 创建新的页面
// @Tags 页面管理
// @Accept json
// @Produce json
// @Param page body models.Page true "页面信息"
// @Success 200 {object} utils.Response{data=models.Page}
// @Router /api/v1/pages [post]
func (pc *PageController) CreatePage(c *gin.Context) {
	var page models.Page
	if err := c.ShouldBindJSON(&page); err != nil {
		utils.ErrorResponse(c, http.StatusBadRequest, "请求参数错误: "+err.Error())
		return
	}

	if err := pc.pageService.CreatePage(&page); err != nil {
		utils.ErrorResponse(c, http.StatusInternalServerError, "创建页面失败: "+err.Error())
		return
	}

	utils.SuccessResponse(c, "创建页面成功", page)
}

// UpdatePage 更新页面（管理端）
// @Summary 更新页面
// @Description 更新页面信息
// @Tags 页面管理
// @Accept json
// @Produce json
// @Param id path int true "页面ID"
// @Param page body models.Page true "页面信息"
// @Success 200 {object} utils.Response{data=models.Page}
// @Router /api/v1/pages/{id} [put]
func (pc *PageController) UpdatePage(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.Atoi(idStr)
	if err != nil {
		utils.ErrorResponse(c, http.StatusBadRequest, "无效的页面ID")
		return
	}

	var page models.Page
	if err := c.ShouldBindJSON(&page); err != nil {
		utils.ErrorResponse(c, http.StatusBadRequest, "请求参数错误: "+err.Error())
		return
	}

	page.ID = id
	if err := pc.pageService.UpdatePage(&page); err != nil {
		utils.ErrorResponse(c, http.StatusInternalServerError, "更新页面失败: "+err.Error())
		return
	}

	utils.SuccessResponse(c, "更新页面成功", page)
}

// DeletePage 删除页面（管理端）
// @Summary 删除页面
// @Description 逻辑删除页面
// @Tags 页面管理
// @Accept json
// @Produce json
// @Param id path int true "页面ID"
// @Success 200 {object} utils.Response
// @Router /api/v1/pages/{id} [delete]
func (pc *PageController) DeletePage(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.Atoi(idStr)
	if err != nil {
		utils.ErrorResponse(c, http.StatusBadRequest, "无效的页面ID")
		return
	}

	if err := pc.pageService.DeletePage(id); err != nil {
		utils.ErrorResponse(c, http.StatusInternalServerError, "删除页面失败: "+err.Error())
		return
	}

	utils.SuccessResponse(c, "删除页面成功", map[string]interface{}{"deleted": true})
}

// GetHierarchyData 获取完整的层级数据
// @Summary 获取完整的层级数据
// @Description 一次性获取所有页面及其关联的分类和项目的完整层级结构
// @Tags 页面管理
// @Accept json
// @Produce json
// @Success 200 {object} utils.Response{data=[]models.Page} "成功"
// @Failure 500 {object} utils.Response "服务器错误"
// @Router /api/v1/hierarchy [get]
func (pc *PageController) GetHierarchyData(c *gin.Context) {
	pages, err := pc.pageService.GetHierarchyData(c)
	if err != nil {
		utils.ErrorResponse(c, http.StatusInternalServerError, err.Error())
		return
	}

	utils.SuccessResponse(c, "获取层级数据成功", pages)
}

// GetAvailableCategories 获取可用的分类列表
// @Summary 获取可用的分类列表
// @Description 获取所有可用的分类，用于关系管理
// @Tags 页面管理
// @Accept json
// @Produce json
// @Success 200 {object} utils.Response{data=[]models.Category} "成功"
// @Failure 500 {object} utils.Response "服务器错误"
// @Router /api/v1/hierarchy/categories [get]
func (pc *PageController) GetAvailableCategories(c *gin.Context) {
	categories, err := pc.pageService.GetAvailableCategories(c)
	if err != nil {
		utils.ErrorResponse(c, http.StatusInternalServerError, err.Error())
		return
	}

	utils.SuccessResponse(c, "获取分类列表成功", categories)
}

// GetAvailableItems 获取可用的项目列表
// @Summary 获取可用的项目列表
// @Description 获取所有可用的项目，用于关系管理
// @Tags 页面管理
// @Accept json
// @Produce json
// @Success 200 {object} utils.Response{data=[]models.Item} "成功"
// @Failure 500 {object} utils.Response "服务器错误"
// @Router /api/v1/hierarchy/items [get]
func (pc *PageController) GetAvailableItems(c *gin.Context) {
	items, err := pc.pageService.GetAvailableItems(c)
	if err != nil {
		utils.ErrorResponse(c, http.StatusInternalServerError, err.Error())
		return
	}

	utils.SuccessResponse(c, "获取项目列表成功", items)
}

// AddCategoryToPage 添加分类到页面
// @Summary 添加分类到页面
// @Description 建立页面和分类的关联关系
// @Tags 页面管理
// @Accept json
// @Produce json
// @Param pageId path int true "页面ID"
// @Param categoryId path int true "分类ID"
// @Success 200 {object} utils.Response "成功"
// @Failure 400 {object} utils.Response "请求参数错误"
// @Failure 500 {object} utils.Response "服务器错误"
// @Router /api/v1/hierarchy/pages/{pageId}/categories/{categoryId} [post]
func (pc *PageController) AddCategoryToPage(c *gin.Context) {
	pageIDStr := c.Param("pageId")
	categoryIDStr := c.Param("categoryId")

	pageID, err := strconv.Atoi(pageIDStr)
	if err != nil {
		utils.ErrorResponse(c, http.StatusBadRequest, "无效的页面ID")
		return
	}

	categoryID, err := strconv.Atoi(categoryIDStr)
	if err != nil {
		utils.ErrorResponse(c, http.StatusBadRequest, "无效的分类ID")
		return
	}

	if err := pc.pageService.AddCategoryToPage(c, pageID, categoryID); err != nil {
		// 根据错误类型返回不同的HTTP状态码
		errorMsg := err.Error()
		if errorMsg == "页面不存在" || errorMsg == "分类不存在" {
			utils.ErrorResponse(c, http.StatusNotFound, errorMsg)
		} else if errorMsg == "该分类已经关联到此页面" {
			utils.ErrorResponse(c, http.StatusConflict, errorMsg)
		} else {
			utils.ErrorResponse(c, http.StatusInternalServerError, errorMsg)
		}
		return
	}

	utils.SuccessResponse(c, "添加分类到页面成功", nil)
}

// RemoveCategoryFromPage 从页面移除分类
// @Summary 从页面移除分类
// @Description 移除页面和分类的关联关系
// @Tags 页面管理
// @Accept json
// @Produce json
// @Param pageId path int true "页面ID"
// @Param categoryId path int true "分类ID"
// @Success 200 {object} utils.Response "成功"
// @Failure 400 {object} utils.Response "请求参数错误"
// @Failure 500 {object} utils.Response "服务器错误"
// @Router /api/v1/hierarchy/pages/{pageId}/categories/{categoryId} [delete]
func (pc *PageController) RemoveCategoryFromPage(c *gin.Context) {
	pageIDStr := c.Param("pageId")
	categoryIDStr := c.Param("categoryId")

	pageID, err := strconv.Atoi(pageIDStr)
	if err != nil {
		utils.ErrorResponse(c, http.StatusBadRequest, "无效的页面ID")
		return
	}

	categoryID, err := strconv.Atoi(categoryIDStr)
	if err != nil {
		utils.ErrorResponse(c, http.StatusBadRequest, "无效的分类ID")
		return
	}

	if err := pc.pageService.RemoveCategoryFromPage(c, pageID, categoryID); err != nil {
		utils.ErrorResponse(c, http.StatusInternalServerError, err.Error())
		return
	}

	utils.SuccessResponse(c, "从页面移除分类成功", nil)
}
